package org.net5ijy.cloud.plugin.feign;

import org.net5ijy.cloud.plugin.feign.core.model.FeignClassAndModel;
import org.net5ijy.cloud.plugin.feign.core.model.FeignClientClass;
import org.net5ijy.cloud.plugin.feign.core.model.FeignModel;
import org.net5ijy.cloud.plugin.feign.core.util.DynamicClasspath;

import java.util.List;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;

/**
 * FeignAutoGenerator
 *
 * @author XGF
 * @date 2020/11/17 8:22
 */
@Mojo(name = "generate", requiresDependencyResolution = ResolutionScope.COMPILE)
public class FeignAutoGenerator extends AbstractMojo {

    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject project;

    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${generate.scanPackage}", readonly = true)
    private String scanPackage;

    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${generate.modelScanPackage}", readonly = true)
    private String modelScanPackage;

    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${generate.manageServerUrl}", readonly = true, required = true)
    private String manageServerUrl;

    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${generate.local}", readonly = true)
    private String local;
    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${generate.feignName}", readonly = true)
    private String feignName;
    @org.apache.maven.plugins.annotations.Parameter(defaultValue = "${generate.generatePackage}", readonly = true)
    private String generatePackage;


    private static final String DEFAULT_SCAN_PACKAGE = "org.net5ijy.cloud";
    private static final String FEIGN_GENERATOR_PLUGIN = "feign-generator-plugin";
    private static final String JAR = ".jar";

    static Log log;
    static String modelScanPath;
    static String manageServer;
    static MavenProject mavenProject;
    static String _feignName;
    static String _generatePackage;


    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        if (scanPackage == null || "".equals(scanPackage)) {
            scanPackage = DEFAULT_SCAN_PACKAGE;
        }
        if (modelScanPackage == null || "".equals(modelScanPackage)) {
            modelScanPackage = DEFAULT_SCAN_PACKAGE;
        }
        if (local == null || "".equals(local)) {
            local = "false";
        }

        if (feignName == null || feignName.isEmpty()) {
            getLog().error(" >> set feignName");
            System.exit(-1);
        }
        if (generatePackage == null || generatePackage.isEmpty()) {
            generatePackage = "feign";
        }

        log = getLog();
        modelScanPath = modelScanPackage;
        manageServer = manageServerUrl;
        mavenProject = project;
        _feignName=feignName;
        _generatePackage=generatePackage;


        try {

            List<String> classpathElements = project.getCompileClasspathElements();

            List<String> compileSourceRoots = project.getCompileSourceRoots();
            String classes = null;

            for (String classpathElement : classpathElements) {
                try {
                    if (classpathElement.contains(FEIGN_GENERATOR_PLUGIN)) {
                        continue;
                    }
                    if (classpathElement.endsWith(JAR)) {
                        DynamicClasspath.loadJar(classpathElement);
                    } else {
                        classes = classpathElement;
                    }
                } catch (Exception e) {
                    getLog().error(e);
                }
            }

            // 加载classes
            if (classes != null) {
                DynamicClasspath.loadDir(classes);
            }

            // 扫描所有controller
            FeignClassAndModel feignClassAndModel = FeignClassGenerateUtil
                    .getFeignClassAndModel(scanPackage, compileSourceRoots);

            feignClassAndModel.setFeignName(feignName);
            feignClassAndModel.setPackageName(generatePackage);

            getLog().info("Feign client list:");

            List<FeignClientClass> feignClientClassList = feignClassAndModel.getFeignClientClasses();
            for (FeignClientClass feignClientClass : feignClientClassList) {
                getLog().info(feignClientClass.toString());
            }

            getLog().info("Feign model list:");

            List<FeignModel> feignModels = feignClassAndModel.getFeignModels();
            for (FeignModel feignModel : feignModels) {
                getLog().info(feignModel.toString());
            }

            // 序列化、发送
            if (local.equals("true")) {
                FeignClassSendUtil.localSave(feignClassAndModel);
            } else {
                FeignClassSendUtil.serializeAndSend(feignClassAndModel);
            }

        } catch (Exception e) {
            getLog().error(e);
        }
    }
}
